﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Globalization;
using System.IO;
using System.Linq;
using SpectrumAnalyser.Common.Csv;
using SpectrumAnalyser.Common.Logs;
using SpectrumAnalyser.Data.Files.SpectrumDatabaseContracts.Repository;
using SpectrumAnalyser.ModelObjects;
using SpectrumAnalyser.ModelObjects.Enum;

namespace SpectrumAnalyser.Data.Files.SpectrumDatabase.Repository
{
    public class NistSpectrumLinesRepository : ISpectrumLinesRepository
    {

        public IList<Peak> FillMatchedPeaks(IList<Peak> peaks, SpectrumDbConnection connection, LinesSearchSettings linesSearchSettings)
        {
            /*var csvConnection = connection as NistSpectrumDbConnection;
            if (ReferenceEquals(csvConnection, null))
            {
                throw new Exception("Connection type is invalid");
            }*/

            double wavelengthCoefficient = peaks.Any(x => x.Point2.X > 2000) ? 1 : 10;

            DataTable table = CsvReader.ReadTable(connection.ConnectionString, ' ');

            var numberFormatInfo = new NumberFormatInfo { NumberDecimalSeparator = "." };
            
            Logger.Log(DateTime.Now.ToString());

            foreach (var peak in peaks)
            {
                IList<SpectrumPoint> localMax = new List<SpectrumPoint>(){peak.Point2};// peak.Points.Where(x => x.Y == peak.Points.MaxBy(y => y.Y).Y).ToList();
                peak.MatchedChemicalElements = peak.MatchedChemicalElements ?? new List<ChemicalElement>();

                foreach (DataRow row in table.Rows)
                {
                    double baseValue;
                    double intencity;
                    if (double.TryParse(row[1].ToString(), NumberStyles.Any, numberFormatInfo, out baseValue) && double.TryParse(row[2].ToString(), out intencity))
                    {
                        baseValue = baseValue/wavelengthCoefficient;
                        foreach (var spectrumPoint in localMax)
                        {
                            if (Math.Abs(spectrumPoint.X - baseValue) < linesSearchSettings.PeakWavelengthRange && Math.Abs(spectrumPoint.Y - intencity)<linesSearchSettings.PeakIntensityRange)
                            {
                                peak.MatchedChemicalElements.Add(new ChemicalElement
                                    {
                                        Name = row[0].ToString(),
                                        OriginalIntensity = intencity
                                    });
                            }
                        }
                    }
                }
            }
            Logger.Log(DateTime.Now.ToString());
            return peaks;
        }

        #region Implementation of ISpectrumPeaksRepository

        public WavelengthMeasure WavelengthMeasure
        {
            get { return WavelengthMeasure.Angstroms; }
        }

        public string ConnectionType
        {
            get { return ModelObjects.Enum.ConnectionType.Nist.ToString(); }
        }

        #endregion
    }
}